package cn.jingyuan.swan.system.service.impl;

import cn.jingyuan.swan.system.service.IpRegionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.File;
import java.lang.reflect.Method;

@Slf4j
@Service
public class IpRegionServiceImpl implements IpRegionService {

    DbConfig config;

    DbSearcher searcher;

    /**
     * 初始化 IP 库
     */
    @PostConstruct
    public void init() {
        try {
            // 因为 jar 无法读取文件，复制创建临时文件
            String tmpDir = System.getProperty("user.dir") + File.separator + "temp";
            String dbPath = tmpDir + File.separator + "ip2region.db";
            log.info("init ip region db path:{}", dbPath);

            File file = new File(dbPath);
            FileUtils.copyInputStreamToFile(IpRegionServiceImpl.class.getClassLoader().getResourceAsStream("data/ip2region.db"), file);
            config = new DbConfig();
            searcher = new DbSearcher(config, dbPath);

            log.info("config:{}", config);
            log.info("searcher:{}", searcher);
        } catch (Exception e) {
            log.error("init ip region error:{}", e);
        }
    }

    @Override
    public String getRegion(String ip) {
        try {
            if (searcher == null) {
                log.error("DbSearcher is null");
                return null;
            }

            long startTime = System.currentTimeMillis();
            //查询算法
            int algorithm = DbSearcher.MEMORY_ALGORITYM;

            Method method = null;
            switch (algorithm) {
                case DbSearcher.BTREE_ALGORITHM:
                    method = searcher.getClass().getMethod("btreeSearch", String.class);
                    break;
                case DbSearcher.BINARY_ALGORITHM:
                    method = searcher.getClass().getMethod("binarySearch", String.class);
                    break;
                case DbSearcher.MEMORY_ALGORITYM:
                    method = searcher.getClass().getMethod("memorySearch", String.class);
                    break;

                default: {

                }
            }

            DataBlock dataBlock = null;
            if (Boolean.FALSE.equals(Util.isIpAddress(ip))) {
                log.warn("warning: Invalid ip address");
            }
            dataBlock = (DataBlock) method.invoke(searcher, ip);
            String result = dataBlock.getRegion();
            long endTime = System.currentTimeMillis();
            return result;
        } catch (Exception e) {
            log.error("error:{}", e);
        }
        return null;
    }

}
